package wsepForum.ui.swing.innerPanels;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import java.util.concurrent.ExecutionException;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.border.MatteBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import wsepForum.common.elements.Message;
import wsepForum.common.elements.Section;
import wsepForum.common.elements.Topic;
import wsepForum.domain.exceptions.SystemFailureException;
import wsepForum.domain.exceptions.UnAuthorizedException;
import wsepForum.network.common.GUIAnswer;
import wsepForum.network.common.GUIAnswer.AnswerType;
import wsepForum.network.common.GUIRequest.RequestType;
import wsepForum.persistance.exceptions.WrongElementIDException;
import wsepForum.ui.swing.SetSwitcher.SetType;
import wsepForum.ui.swing.outerPanels.AOuterPanel;
import wsepForum.ui.swing.workers.ForumWorker;
import javax.swing.JScrollPane;

public class TopicViewPanel extends AInnerPanel {

	private static final long serialVersionUID = 8634357850385954881L;
	private Topic topic;
	private Message message;
	private JTextArea textArea;

	public TopicViewPanel(Topic top, AOuterPanel oPanel) {
		super(oPanel);
		this.topic = top;
		setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
		setLayout(null);
		setBackground(new Color(230, 230, 250));
		setBounds(20, 93, 716, 364);

		final JButton btnDelete = new JButton("Delete");
		final JButton btnAddMessage = new JButton("Add Message");
		final JButton btnReply = new JButton("Reply");
		final JButton btnEdit = new JButton("Edit");
		final JButton btnBack = new JButton("Back");

		SetType setType = outerPanel.getCurrentSet();
		final JLabel lblTopic = new JLabel("Topic\r\n");
		lblTopic.setText(this.topic.getHeadLine());
		final JLabel lblMessages = new JLabel("Messages");

		Vector<String> mesVector = new Vector<String>();
		for (Message mes : this.topic.getAllMessages()) {
			mesVector.add(mes.getHeadLine());
		}
		final JList list = new JList(mesVector);

		JScrollPane scrollPane = new JScrollPane(list);
		scrollPane.setBounds(10, 89, 316, 192);
		add(scrollPane);

		this.textArea = new JTextArea();
		this.textArea.enableInputMethods(false);
		JScrollPane scrollPane_1 = new JScrollPane(textArea);
		scrollPane_1.setBounds(367, 92, 324, 261);
		add(scrollPane_1);

		lblTopic.setHorizontalAlignment(SwingConstants.CENTER);
		lblTopic.setFont(new Font("Cooper Black", Font.PLAIN, 18));
		lblTopic.setBounds(161, 11, 393, 43);
		add(lblTopic);

		list.addListSelectionListener(new ListSelectionListener() {
			@Override
			public void valueChanged(ListSelectionEvent e) {
				ForumWorker<JPanel> worker = new ForumWorker<JPanel>(outerPanel.getConnection()){
					@Override
					protected JPanel doInBackground() throws Exception {
						AInnerPanel returnedPanel = TopicViewPanel.this;
						int selectedMsg = list.getSelectedIndex();
						int askedMsgID = topic.getMessage(selectedMsg).getElementID();
						GUIAnswer ans = request(RequestType.GET_MESSAGE, new Object[] {askedMsgID}) ;
						outerPanel.setNumOfConnected(ans.getNumOfConnected());
						if(ans.getAnswerType().equals(AnswerType.ANSWER)){
							message = (Message)ans.getArguments()[0];
							btnReply.setEnabled(true);
							btnEdit.setEnabled((Boolean)ans.getArguments()[1]);
							btnDelete.setEnabled((Boolean)ans.getArguments()[2]);
							textArea.setText("Message by: " + (message.getUserName() != null ? message.getUserName() : "Guest") +
									"\nDate: " + message.getTimeStamp() +
									"\nHeadline: " + message.getHeadLine()+
									"\n--------------------------------------\n" + message.getBody());
						}
						else {
							returnedPanel = handleShowMsgExceptions((Exception) ans.getArguments()[0]);
						}
						return returnedPanel;
					}
					
					private AInnerPanel handleShowMsgExceptions(Exception thrown){
						try {
							throw thrown;
						} catch (WrongElementIDException e) {
							JOptionPane.showMessageDialog(null, "the message you are trying to open was deleted by another user", "Topic deleted",JOptionPane.ERROR_MESSAGE);
							return TopicViewPanel.this;
						} catch (UnAuthorizedException e) {
							JOptionPane.showMessageDialog(null, "you are not authorized to write message", "UnAuthorized use",JOptionPane.ERROR_MESSAGE);
							return TopicViewPanel.this;
						} catch (SystemFailureException e) {
							JOptionPane.showMessageDialog(null, "system is unavalible at the moment, please try again later\n" + e.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
							return requestHomePanel(outerPanel);
						} catch (Exception e) {
							JOptionPane.showMessageDialog(null, "operation failed! please try again\n" + e.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
							return requestHomePanel(outerPanel);
						}
					}
				};
				worker.execute();
			}
		});

		lblMessages.setFont(new Font("Cooper Black", Font.PLAIN, 16));
		lblMessages.setBounds(10, 53, 266, 25);
		add(lblMessages);

		btnDelete.setFont(new Font("Tahoma", Font.PLAIN, 10));
		btnDelete.setBounds(13, 327, 95, 21);
		btnDelete.setEnabled(false);
		btnDelete.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent arg0) {
				ForumWorker<AInnerPanel> worker = new ForumWorker<AInnerPanel>(outerPanel.getConnection()){
					@Override
					protected AInnerPanel doInBackground() throws Exception {
						int selectedMsg = list.getSelectedIndex();
						int askedMsgID = topic.getMessage(selectedMsg).getElementID();
						GUIAnswer ans = request(RequestType.GET_MESSAGE, new Object[] {askedMsgID}) ;
						outerPanel.setNumOfConnected(ans.getNumOfConnected());
						AInnerPanel returnedPanel = null;
						if(ans.getAnswerType().equals(AnswerType.ANSWER)){
							ans = request(RequestType.DELETE_MESSAGE, new Object[] {topic.getElementID(), askedMsgID}) ;
							outerPanel.setNumOfConnected(ans.getNumOfConnected());
							if(ans.getAnswerType().equals(AnswerType.ANSWER)){
								if (selectedMsg == 0) {// removing the first message will remove the whole topic
									returnedPanel = new SectionPanel((Section)ans.getArguments()[0], (Boolean)ans.getArguments()[1], outerPanel);
								}
								else {
									returnedPanel = new TopicViewPanel((Topic)ans.getArguments()[0],outerPanel);
								}
							}
							else {
								JOptionPane.showMessageDialog(null, "Cannot delete message\n"+ans.getArguments()[0]);
							}
						}
						else {
							JOptionPane.showMessageDialog(null, "Cannot display message\n"+ans.getArguments()[0]);
						}
						return returnedPanel;
					}
					@Override
					public void done(){
						try {
							outerPanel.swapInnerPanel(get());
						} catch (InterruptedException e) {
						} catch (ExecutionException e) {
						}
					}
				};
				worker.execute();
			}
		});
		if (setType != SetType.GUEST)
			add(btnDelete);

		btnAddMessage.setFont(new Font("Tahoma", Font.PLAIN, 10));
		btnAddMessage.setBounds(10, 293, 98, 23);
		btnAddMessage.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent arg0) {
				ForumWorker<AInnerPanel> worker = new ForumWorker<AInnerPanel>(outerPanel.getConnection()){
					@Override
					protected AInnerPanel doInBackground() throws Exception {
						return new EditorPanel(outerPanel,topic);
					}
					@Override
					public void done(){
						try {
							outerPanel.swapInnerPanel(get());
						} catch (InterruptedException e) {
							e.printStackTrace();
						} catch (ExecutionException e) {
							e.printStackTrace();
						}
					}
				};
				worker.execute();
			}
		});
		if (setType != SetType.GUEST)
			add(btnAddMessage);

		btnReply.setFont(new Font("Tahoma", Font.PLAIN, 10));
		btnReply.setBounds(118, 293, 98, 23);
		btnReply.setEnabled(false);
		btnReply.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent arg0) {
				ForumWorker<AInnerPanel> worker = new ForumWorker<AInnerPanel>(outerPanel.getConnection()){
					@Override
					protected AInnerPanel doInBackground() throws Exception {
						int selectedMsg = list.getSelectedIndex();
						int askedMsgID = topic.getMessage(selectedMsg).getElementID();
						GUIAnswer ans = request(RequestType.GET_MESSAGE, new Object[] {askedMsgID}) ;
						outerPanel.setNumOfConnected(ans.getNumOfConnected());
						AInnerPanel returnedPanel = null;
						if(ans.getAnswerType().equals(AnswerType.ANSWER)){
							returnedPanel = new EditorPanel(outerPanel,topic,(Message)ans.getArguments()[0]);
						}
						else {
							returnedPanel = handleReplyExceptions((Exception) ans.getArguments()[0]);
						}
						return returnedPanel;
					}
					@Override
					public void done(){
						try {
							outerPanel.swapInnerPanel(get());
						} catch (InterruptedException e) {
							outerPanel.swapInnerPanel(handleReplyExceptions(e));
						} catch (ExecutionException e) {
							outerPanel.swapInnerPanel(handleReplyExceptions(e));
						}
					}
					
					private AInnerPanel handleReplyExceptions(Exception thrown){
						try {
							throw thrown;
						} catch (WrongElementIDException e) {
							JOptionPane.showMessageDialog(null, "the message you are trying to open was deleted by another user", "Topic deleted",JOptionPane.ERROR_MESSAGE);
							return TopicViewPanel.this;
						} catch (UnAuthorizedException e) {
							JOptionPane.showMessageDialog(null, "you are not authorized to write message", "UnAuthorized use",JOptionPane.ERROR_MESSAGE);
							return TopicViewPanel.this;
						} catch (SystemFailureException e) {
							JOptionPane.showMessageDialog(null, "system is unavalible at the moment, please try again later\n" + e.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
							return requestHomePanel(outerPanel);
						} catch (Exception e) {
							JOptionPane.showMessageDialog(null, "operation failed! please try again\n" + e.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
							return requestHomePanel(outerPanel);
						}
					}
				};
				worker.execute();
			}
		});
		if (setType != SetType.GUEST)
			add(btnReply);

		btnEdit.setFont(new Font("Tahoma", Font.PLAIN, 10));
		btnEdit.setBounds(228, 293, 98, 23);
		btnEdit.setEnabled(false);
		btnEdit.addActionListener(new ActionListener(){
			@Override
			public void actionPerformed(ActionEvent arg0) {
				ForumWorker<AInnerPanel> worker = new ForumWorker<AInnerPanel>(outerPanel.getConnection()){
					@Override
					protected AInnerPanel doInBackground() throws Exception {
						int selectedMsg = list.getSelectedIndex();
						int askedMsgID = topic.getMessage(selectedMsg).getElementID();
						GUIAnswer ans = request(RequestType.GET_MESSAGE, new Object[] {askedMsgID}) ;
						outerPanel.setNumOfConnected(ans.getNumOfConnected());
						AInnerPanel returnedPanel = null;
						if(ans.getAnswerType().equals(AnswerType.ANSWER)){
							returnedPanel = new EditorPanel(outerPanel,(Message)ans.getArguments()[0]);
						}
						else {
							returnedPanel = handleEditTopicExceptions((Exception) ans.getArguments()[0]);
						}
						return returnedPanel;
					}
					@Override
					public void done(){
						try {
							outerPanel.swapInnerPanel(get());
						} catch (InterruptedException e) {
							outerPanel.swapInnerPanel(handleEditTopicExceptions(e));
						} catch (ExecutionException e) {
							outerPanel.swapInnerPanel(handleEditTopicExceptions(e));
						}
					}

					private AInnerPanel handleEditTopicExceptions(Exception thrown){
						try {
							throw thrown;
						} catch (WrongElementIDException e) {
							JOptionPane.showMessageDialog(null, "the message you are trying to open was deleted by another user", "Topic deleted",JOptionPane.ERROR_MESSAGE);
							return TopicViewPanel.this;
						} catch (UnAuthorizedException e) {
							JOptionPane.showMessageDialog(null, "you are not authorized to edit this message", "UnAuthorized use",JOptionPane.ERROR_MESSAGE);
							return TopicViewPanel.this;
						} catch (SystemFailureException e) {
							JOptionPane.showMessageDialog(null, "system is unavalible at the moment, please try again later\n" + e.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
							return requestHomePanel(outerPanel);
						} catch (Exception e) {
							JOptionPane.showMessageDialog(null, "operation failed! please try again\n" + e.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
							return requestHomePanel(outerPanel);
						}
					}
				};
				worker.execute();
			}
		});
		if (setType != SetType.GUEST)
			add(btnEdit);

		btnBack.setBounds(615, 11, 91, 23);
		btnBack.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent arg0) {
				ForumWorker<AInnerPanel> worker = new ForumWorker<AInnerPanel>(outerPanel.getConnection()){

					@Override
					protected AInnerPanel doInBackground() throws Exception {
						GUIAnswer ans = request(RequestType.GET_SETCION, new Object[] {topic.getParentID()});
						outerPanel.setNumOfConnected(ans.getNumOfConnected());
						AInnerPanel returnedPanel = null;
						if(ans.getAnswerType().equals(AnswerType.ANSWER)){
							returnedPanel = new SectionPanel((Section) ans.getArguments()[0],(Boolean)ans.getArguments()[1],outerPanel);
						}
						else {
							returnedPanel = handleBackExceptions((Exception) ans.getArguments()[0]);
						}
						return returnedPanel;
					}

					@Override
					public void done(){
						try {
							outerPanel.swapInnerPanel(get());
						} catch (InterruptedException e) {
							outerPanel.swapInnerPanel(handleBackExceptions(e));
						} catch (ExecutionException e) {
							outerPanel.swapInnerPanel(handleBackExceptions(e));
						}
					}

					private AInnerPanel handleBackExceptions(Exception thrown){
						try {
							throw thrown;
						} catch (WrongElementIDException e) {
							JOptionPane.showMessageDialog(null, "the topic you are trying to open was deleted by another user", "Topic deleted",JOptionPane.ERROR_MESSAGE);
							return requestHomePanel(outerPanel);
						} catch (SystemFailureException e) {
							JOptionPane.showMessageDialog(null, "system is unavalible at the moment, please try again later\n" + e.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
							return requestHomePanel(outerPanel);
						} catch (Exception e) {
							JOptionPane.showMessageDialog(null, "operation failed! please try again\n" + e.getMessage(), "Error",JOptionPane.ERROR_MESSAGE);
							return requestHomePanel(outerPanel);
						}
					}
				};
				worker.execute();
			}
		});
		add(btnBack);

	}
}
